package com.ruoyi.law.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deepoove.poi.XWPFTemplate;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.law.domain.dto.LawFileDTO;
import com.ruoyi.law.domain.entity.LawFile;
import com.ruoyi.law.domain.entity.LawPresets;
import com.ruoyi.law.service.ILawFileService;
import com.ruoyi.law.service.ILawOrderService;
import com.ruoyi.law.service.ILawPresetsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 文书生成 前端控制器
 * </p>
 *
 * @author code
 * @since 2023-04-11
 */
@Slf4j
@Api(tags = "文书生成功能")
@Validated
@RestController
@RequestMapping("/file")
public class LawFileController extends BaseController {

    private static final String LINUX_FILE_PATH = "/home/lawfile/";
    private static final String WINDOWS_FILE_PATH = "D:\\uploadFile\\";
    @Autowired
    private ILawFileService fileService;
    @Autowired
    private ILawOrderService orderService;
    @Autowired
    private ILawPresetsService presetsService;

    public static void templateWrite(File file, Map<String, Object> params, String outFilePath) throws Exception {
        XWPFTemplate template = XWPFTemplate.compile(file).render(params);
        FileOutputStream out = new FileOutputStream(outFilePath);
        template.write(out);
        out.flush();
        out.close();
        template.close();
    }

    @Anonymous
    @ApiOperation("文书生成表单提交")
    @PostMapping("/fileForm")
    public R<String> fileForm(@RequestBody LawFileDTO lawFile) {
        long uuid = IdUtil.getSnowflakeNextId();
        lawFile.setId(uuid);
        fileService.save(lawFile);
        return R.ok(String.valueOf(uuid));
    }

    @Anonymous
    @ApiOperation("文书生成")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文书id", required = true),
            @ApiImplicitParam(name = "orderNumber", value = "订单号", required = true),
            @ApiImplicitParam(name = "smallType", value = "大类", required = true),
            @ApiImplicitParam(name = "bigType", value = "小类", required = true)
    })
    @GetMapping("/fileGenerate")
    public void fileGenerate(HttpServletResponse response, String id, String orderNumber,
                             String smallType, String bigType) throws Exception {
        LawFile lawFile = fileService.getById(id);
        Assert.notNull(lawFile, "文书不存在");
//        Map<String, Object> map = orderService.queryFileOrders(orderNumber);
//        String tradeState = MapUtil.getStr(map, "tradeState");
//        // 判断是否支付成功
//        if (!StrUtil.equals("SUCCESS", tradeState)) {
//            throw new RuntimeException("订单未支付,请先支付");
//        }

        // 判断当前系统
        String os = System.getProperty("os.name");
        String filePath = "";
        if (os.toLowerCase().startsWith("win")) {
            filePath = WINDOWS_FILE_PATH;
        } else {
            filePath = LINUX_FILE_PATH;
        }
        File file = new File(filePath + "民事起诉状_模板.docx");

        Map<String, Object> params = BeanUtil.beanToMap(lawFile);
        // 处理参数预设语句
        handMap(params, smallType, bigType);

        String outPath = filePath + IdUtils.fastSimpleUUID() + ".docx";
        templateWrite(file, params, outPath);
        // 返回前端文件流 让其下载
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("民事起诉状.docx", "UTF-8"));

        try {
            InputStream stream = new FileInputStream(outPath);
            ServletOutputStream out = response.getOutputStream();
            byte[] buff = new byte[1024];
            int length;
            while ((length = stream.read(buff)) > 0) {
                out.write(buff, 0, length);
            }
            stream.close();
            out.close();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理参数预设语句
     *
     * @param params 参数
     */
    private void handMap(Map<String, Object> params, String smallType, String bigType) {
//        String 预设 = MapUtil.getStr(params, "预设");
        LambdaQueryWrapper<LawPresets> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LawPresets::getBigType, bigType)
                .eq(LawPresets::getSmallType, smallType);
        LawPresets one = presetsService.getOne(wrapper);
        String 预设 = one.getJson();

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value == null) {
                String 预设无 = handJson(预设, key + "无", null);
                if (StrUtil.isNotBlank(预设无)) {
                    params.put(key, 预设无);
                }
            } else {
                // 日期转换
                if (value instanceof Date) {
                    value = DateUtil.format((Date) value, DatePattern.CHINESE_DATE_PATTERN);
                    entry.setValue(value);
                }
                String 预设有 = handJson(预设, key + "有", value.toString());
                if (StrUtil.isNotBlank(预设有)) {
                    params.put(key, 预设有);
                }
            }
        }
    }

    /**
     * 处理json 返回一个随机的预设字段
     *
     * @param json        json
     * @param key         有或无
     * @param placeholder 占位符
     * @return {@link String}
     */
    private String handJson(String json, String key, String placeholder) {
        JSONObject jsonObject = JSONUtil.parseObj(json);
        // 将jsonObject中key包含‘key’的值筛选出来
        List<String> res = jsonObject.keySet().stream().filter(e -> e.contains(key))
                .map(jsonObject::getStr).collect(Collectors.toList());

        // 将res中{}替换成占位符
        res = res.stream().map(e -> StrUtil.replace(e, "{}", placeholder))
                .collect(Collectors.toList());
        // 随机取一个
        if (CollectionUtil.isNotEmpty(res)) {
            return res.get(RandomUtil.randomInt(0, res.size()));
        }
        return null;
    }

}
